#include "stdafx.h"
#include "ProteinVista.h"

#include "DotNetInterface.h"
#include "PlugInInterface.h"
#include "MainFrm.h"
#include "EasyAccessFunction.h"
#include "ProteinVistaRenderer.h"
#include "Utility.h"

#using <mscorlib.dll>
#using <System.Xml.dll>

#ifdef _MANAGED

using namespace System;
using namespace System::Xml;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::CodeDom;
using namespace System::CodeDom::Compiler;
using namespace System::Windows::Forms;
using namespace Microsoft::CSharp;
using namespace System::Reflection;
using namespace ProteinInsightInterface;
using namespace CompileScript;

void TutorialCallback(CString strID , CString strDLL)
{
	if ( ((CProteinVistaApp*)(AfxGetApp()))->m_bRunningPlugin == TRUE )
	{
		CString strMsg(_T("Tutorial Script is running now."));
		OutputTextMsg(strMsg);
		return ;
	}

	((CProteinVistaApp*)(AfxGetApp()))->m_bRunningPlugin = TRUE;

	CDotNetProteinInsight ^ proteinInsight = nullptr;
	GC::Collect();

	try
	{
		proteinInsight = gcnew CDotNetProteinInsight();
		proteinInsight->WorkspaceInit();

		TRACE(_T("%s\n"), strID);

		if (strID == _T("OpenPDB1NME") )
		{
			proteinInsight->Open(_T("1NME"));
		}
		else if (strID == _T("RotateModel")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));

			for ( INT32 i = 0 ; i < 100 ; i++ )
			{
				proteinInsight->VPs[0]->RotationY(0.1);
				proteinInsight->Idle(30);
			}
			for ( INT32 i = 0 ; i < 100 ; i++ )
			{
				proteinInsight->VPs[0]->RotationX(0.1);
				proteinInsight->Idle(30);
			}
		}
		else if (strID == _T("TranslateModel")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));

			for ( INT32 i = 0 ; i < 80 ; i++ )
			{
				proteinInsight->VPs[0]->Move(-0.2,0,0);
				proteinInsight->Idle(25);
			}
			for ( INT32 i = 0 ; i < 120 ; i++ )
			{
				proteinInsight->VPs[0]->Move(0.2,0,0);
				proteinInsight->Idle(25);
			}
			for ( INT32 i = 0 ; i < 80 ; i++ )
			{
				proteinInsight->VPs[0]->Move(-0.2,0,0);
				proteinInsight->Idle(25);
			}
		}
		else if (strID == _T("ForwardBackwardCamera")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));

			Vector3 camera = proteinInsight->Property->Camera->Position;
			for ( INT32 i = 0 ; i < 50 ; i++ )
			{
				camera.Z -= 1.0f;
				proteinInsight->Property->Camera->Position = camera;
				proteinInsight->Idle(30);
			}
			camera = proteinInsight->Property->Camera->Position;
			for ( INT32 i = 0 ; i < 50 ; i++ )
			{
				camera.Z += 1.0f;
				proteinInsight->Property->Camera->Position = camera;
				proteinInsight->Idle(30);
			}
		}
		else if (strID == _T("TreeViewPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_PDB_TREE);
		}
		else if (strID == _T("ResidueViewPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_RESIDUE);
		}
		else if (strID == _T("VPListPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);
		}
		else if (strID == _T("PropertiesPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_PROP);
		}
		else if (strID == _T("ScriptInputPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SCRIPT_INPUT);
		}
		else if (strID == _T("ScriptOutputPane")) 
		{
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SCRIPT_OUTPUT);
		}
		else if (strID == _T("OpenPDBINME")) 
		{
			proteinInsight->Open(_T("1NME"));
		}
		else if (strID == _T("SelectChainA")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_RESIDUE);
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_PDB_TREE);
			proteinInsight->PDBs[0]->SetSelect(false, true);
			proteinInsight->PDBs[0]->Chains[0]->SetSelect(true, true);
		}
		else if (strID == _T("ShowStickModel")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));

			proteinInsight->AddVP(proteinInsight->PDBs[0]->Chains[0], IProteinInsight::IDisplayStyle::Stick);

			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);
		}
		else if (strID == _T("SelectChainB")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_RESIDUE);
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_PDB_TREE);
			proteinInsight->PDBs[0]->SetSelect(false, true);
			proteinInsight->PDBs[0]->Chains[1]->SetSelect(true, true);
		}
		else if (strID == _T("ShowSurfaceModel")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));

			proteinInsight->AddVP(proteinInsight->PDBs[0]->Chains[1], IProteinInsight::IDisplayStyle::Surface);

			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);
		}
		else if (strID == _T("ShowHideEachVP")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);

			for each ( IVP ^ vp in proteinInsight->VPs )
			{
				vp->Show = false;
				proteinInsight->Idle(1000);
			}

			for each ( IVP ^ vp in proteinInsight->VPs )
			{
				vp->Show = true;
				proteinInsight->Idle(1000);
				vp->Show = false;
				proteinInsight->Idle(1000);
				vp->Show = true;
				proteinInsight->Idle(1000);
				vp->Show = false;
				proteinInsight->Idle(1000);
			}

			for each ( IVP ^ vp in proteinInsight->VPs )
			{
				vp->Show = true;
				proteinInsight->Idle(1000);
			}
		}
		else if (strID == _T("ChangeVisualizationProperty")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	 proteinInsight->Open(_T("1NME"));
			IVP ^ vpRibbon = proteinInsight->AddVP(proteinInsight->PDBs[0]->GetChains("A")[0], IProteinInsight::IDisplayStyle::Ribbon);
			IVP ^ vpSurface = proteinInsight->AddVP(proteinInsight->PDBs[0]->GetChains("B")[0], IProteinInsight::IDisplayStyle::Surface);

			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);
			vpRibbon->Select = true;
			proteinInsight->Idle(3000);

			for ( INT32 i = 0 ; i < 70 ; i++ )
			{
				vpRibbon->RotationY(0.1);
				proteinInsight->Idle(50);
				if ( i == 30 )
				{
					((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_PROP);
					vpRibbon->Property->ColorScheme = IProperty::IColorScheme::Residue;
				}
			}
			
			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);
			vpSurface->Select = true;
			proteinInsight->Idle(1000);

			for ( INT32 i = 0 ; i < 70 ; i++ )
			{
				vpSurface->RotationY(0.1);
				proteinInsight->Idle(50);
				if ( i == 30 )
				{
					((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_PROP);
					vpSurface->Property->ColorScheme = IProperty::IColorScheme::Progressive;
				}
			}

		}
		else if (strID == _T("DeleteVP")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));
			IVP ^ vpRibbon = proteinInsight->AddVP(proteinInsight->PDBs[0]->Chains[0], IProteinInsight::IDisplayStyle::Ribbon);
			IVP ^ vpSurface = proteinInsight->AddVP(proteinInsight->PDBs[0]->Chains[1], IProteinInsight::IDisplayStyle::Surface);

			((CMainFrame*)AfxGetMainWnd())->SetPaneForeground(IDR_PANE_SELECTION_LIST);

			proteinInsight->DeleteVP(vpRibbon);
			proteinInsight->Idle(2000);

			proteinInsight->DeleteVP(vpSurface);
			proteinInsight->Idle(2000);
		}
		else if (strID == _T("VariousSelect")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	 proteinInsight->Open(_T("1NME"));

			IChain ^ chain = proteinInsight->PDBs[0]->GetChains("A")[0];

			proteinInsight->SetSelect(false, true);
			
			for each ( IResidue ^ residue in chain->Residues )
			{
				if ( residue->SSType != IResidue::ISSType::None )
				{
					residue->SetSelect(true, false);
				}
			}
			proteinInsight->UpdateSelect();

			IVP ^ vpBallStick = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::BallnStick);
			IVP ^ vpSurface = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::Surface);
		}
		else if (strID == _T("VariousVisualization")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	 proteinInsight->Open(_T("1NME"));

			IChain ^ chain = proteinInsight->PDBs[0]->GetChains("A")[0];

			proteinInsight->SetSelect(false, true);
			
			for each ( IResidue ^ residue in chain->Residues )
			{
				if ( residue->SSType != IResidue::ISSType::None )
				{
					residue->SetSelect(true, false);
				}
			}
			proteinInsight->UpdateSelect();

			IVP ^ vpBallStick = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::BallnStick);
			IVP ^ vpBallRibbon = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::Ribbon);
			IVP ^ vpSurface = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::Surface);

			vpSurface->Property->ColorScheme = IProperty::IColorScheme::Residue;
			vpSurface->PropertySurface->Transparency = 30;

			proteinInsight->SetSelect(false, true);
			
			for each ( IResidue ^ residue in chain->Residues )
			{
				if ( residue->SSType == IResidue::ISSType::None )
				{
					residue->SetSelect(true, false);
				}
			}
			proteinInsight->UpdateSelect();

			IVP ^ vpSurface2 = proteinInsight->AddVP(IProteinInsight::IDisplayStyle::Surface);
			vpSurface2->Property->ColorScheme = IProperty::IColorScheme::SingleColor;
			vpSurface2->PropertySurface->Transparency = 20;
		}
		else if (strID == _T("OpenPDB1NME")) 
		{
			if ( proteinInsight->PDBs->Count == 0 )	proteinInsight->Open(_T("1NME"));
		}
		else if (strID == _T("WriteFollowingCode")) 
		{

		}
		else if (strID == _T("RunScriptCode")) 
		{
			((CProteinVistaApp*)(AfxGetApp()))->m_bRunningPlugin = FALSE;
			RunPlugInDLL( ((CProteinVistaApp*)(AfxGetApp()))->m_strBaseTutorialPath + _T("TutorialRunScriptCode.dll"), FALSE );
		}

		proteinInsight->WorkspaceDestroy();
	}
	catch ( Exception ^ e )
	{
		if ( proteinInsight != nullptr )
			proteinInsight->Utility->OutputMsg(e->ToString());
		else
			System::Windows::Forms::MessageBox::Show(e->ToString());
	}

	proteinInsight = nullptr;
	GC::Collect();

	((CProteinVistaApp*)(AfxGetApp()))->m_bRunningPlugin = FALSE;
}


#endif
